---
title: Handling Webpack
desc: (@quasar/app-webpack) How to manage Webpack in a Quasar app.
related:
  - /quasar-cli-webpack/quasar-config-file
---
The build system uses Webpack to create your website/app. Don't worry if you aren't acquainted with Webpack. Out of the box, you won't need to configure it because it already has everything set up.

## Usage with quasar.config file
For cases where you need to tweak the default Webpack config you can do so by editing the `/quasar.config` file and configuring `build > extendWebpack (cfg)` method or `build > chainWebpack (chain)`.

Example of adding ESLint loader to Webpack (assuming you've installed it):

```js /quasar.config file
build: {
  extendWebpack (cfg, { isServer, isClient }) {
    cfg.module.rules.push({
      enforce: 'pre',
      test: /\.(js|vue)$/,
      loader: 'eslint-loader',
      exclude: /(node_modules|quasar)/
    })
  }
}
```

Notice that you don't need to return anything. The parameter of extendWebpack(cfg) is the Webpack configuration Object generated by Quasar for you. You can add/remove/replace anything from it, assuming you really know what you are doing.

Equivalent quasar.conf for chainWebpack():

```js /quasar.config file
build: {
  chainWebpack (chain, { isServer, isClient }) {
    chain.module.rule('eslint')
      .test(/\.(js|vue)$/)
      .enforce('pre')
      .exclude
        .add((/[\\/]node_modules[\\/]/))
        .end()
      .use('eslint-loader')
        .loader('eslint-loader')
  }
}
```

::: tip
The method `chainWebpack()` supplies a [webpack-chain](https://github.com/neutrinojs/webpack-chain) Object. You might want to check its documentation page.
:::

::: warning
`chainWebpack()` gets executed **before** `extendWebpack()`.

The two examples above are equivalent. Do NOT use both methods to tamper for the same thing!
:::

## Inspecting Webpack Config
Quasar CLI offers a useful command for this:

```bash
$ quasar inspect -h

  Description
    Inspect Quasar generated Webpack config

  Usage
    $ quasar inspect
    $ quasar inspect -c build
    $ quasar inspect -m electron -p 'module.rules'

  Options
    --cmd, -c        Quasar command [dev|build] (default: dev)
    --mode, -m       App mode [spa|ssr|pwa|cordova|electron] (default: spa)
    --depth, -d      Number of levels deep (default: 5)
    --path, -p       Path of config in dot notation
                        Examples:
                          -p module.rules
                          -p plugins
    --help, -h       Displays this message
```

## Webpack Aliases
Quasar comes with a bunch of useful Webpack aliases preconfigured. You can use them anywhere in your project and webpack will resolve the correct path.

| Alias | Resolves to |
| --- | --- |
| `src` | /src |
| `app` | / |
| `components` | /src/components |
| `layouts` | /src/layouts |
| `pages` | /src/pages |
| `assets` | /src/assets |
| `boot` | /src/boot |
| `stores` | /src/stores (Pinia stores) |

Also if you configure to build with the Vue compiler version (quasar.config file > build > vueCompiler: true), `vue$` resolves to  `vue/dist/vue.esm.js`.

### Adding Webpack aliases

To add your own alias you can extend the webpack config and merge it with the existing alias.
Use the `path.resolve` helper to resolve the path to your intended alias.

```js /quasar.config file
const path = require('node:path')

module.exports = function (ctx) {
  return {
    build: {
      extendWebpack (cfg, { isServer, isClient }) {
        cfg.resolve.alias = {
          ...cfg.resolve.alias, // This adds the existing alias

          // Add your own alias like this
          myalias: path.resolve(__dirname, './src/somefolder'),
        }
      }
    }
  }
}
```

Equivalent with chainWebpack():

```js /quasar.config file
const path = require('node:path')

module.exports = function (ctx) {
  return {
    build: {
      chainWebpack (chain, { isServer, isClient }) {
        chain.resolve.alias
          .set('myalias', path.resolve(__dirname, './src/somefolder'))
      }
    }
  }
}
```

## Webpack v5 compatibility issues

Quasar App CLI is using Webpack v5. If you are moving your existing project to Quasar from a Webpack v4 project, you might have some compatibility issues with 3rd party libraries. Webpack v5 removed the Node.js polyfills for the web client builds. If you are using packages for the web client that rely on Node.js API, you will get errors saying that some packages are missing. Examples: `Buffer`, `crypto`, `os`, `path`, `stream`, `assert`.

These need to be addressed by the package owners. But if you prefer not to wait and just want to run your app/website (with a bit of risk), then you can manually install `node-polyfill-webpack-plugin` (`yarn add --dev node-polyfill-webpack-plugin`) and reference it in `quasar.config file > build > chainWebpack`. Example:

```js /quasar.config file
build: {
  chainWebpack (chain) {
    const nodePolyfillWebpackPlugin = require('node-polyfill-webpack-plugin')
    chain.plugin('node-polyfill').use(nodePolyfillWebpackPlugin)
  }
}
```

## Webpack loaders
The build system uses Webpack, so it relies on using webpack loaders to handle different types of files (js, css, styl, scss, json, and so on). By default, the most used loaders are provided by default.

### Installing loaders
Let's take an example. You want to be able to import `.json` files. **Out of the box, Quasar supplies json support so you don't actually need to follow these steps, but for the sake of demonstrating how to add a loader, we'll pretend Quasar doesn't offer it.**

So, you need a loader for it. You search Google to see what webpack loader you need. In this case, it's "json-loader". We first install it:

``` bash
$ yarn add --dev json-loader
```

After installing your new loader, we want to tell Webpack to use it. So we edit the `/quasar.config` file and change `build.extendWebpack()` to add entries to `module/rules` for this new loader:

```js /quasar.config file
build: {
  extendWebpack (cfg) {
    cfg.module.rules.push({
      test: /\.json$/,
      loader: 'json-loader'
    })
  }
}
```

Equivalent with chainWebpack():

```js /quasar.config file
build: {
  chainWebpack (chain) {
    chain.module.rule('json')
      .test(/\.json$/)
      .use('json-loader')
        .loader('json-loader')
  }
}
```

And you're done.

### PostCSS

Styles in `*.vue` files (and all other style files) are piped through PostCSS by default, so you don't need to use a specific loader for it.

By default, PostCSS is configured to use Autoprefixer. Take a look at `/postcss.config.cjs` where you can tweak it if you need to.

### Pug
First, you need to install some dependencies:

```bash
$ yarn add --dev pug pug-plain-loader
```

Then you need to extend the webpack configuration through the `/quasar.config` file:

```js /quasar.config file
build: {
  extendWebpack (cfg) {
    cfg.module.rules.push({
      test: /\.pug$/,
      loader: 'pug-plain-loader'
    })
  }
}
```

Equivalent with chainWebpack():

```js /quasar.config file
build: {
  chainWebpack (chain) {
    chain.module.rule('pug')
      .test(/\.pug$/)
      .use('pug-plain-loader')
        .loader('pug-plain-loader')
  }
}
```

### Coffeescript
If you are using Coffeescript then you need to EITHER disable ESLint OR tell ESLint which Vue components are using Coffeescript.

Note that `vue-loader` uses `lang="coffee"` to identify components which are using Coffeescript, but `lang="coffee"` is not recognizable for ESLint. Fortunately, ESLint (following traditional HTML) uses `type="xxx"` to identify the type of scripts. As long as a `<script>` tag has any `type` other than `javascript`, ESLint would mark the script as non-javascript, and skips linting it. Coffeescript's convention is to use `type="text/coffeescript"` to identify itself. Therefore, in your Vue components which are using Coffeescript, using both `lang` and `type` to avoid ESLint warnings:

```html
<template>
  ...
</template>
<script lang="coffee" type="text/coffeescript">
  ...
</script>
```
